<template>
  <div class="annotation-page">
    <div class="toolbar">
      <button @click="clearAll" class="tool-btn">清空所有</button>
      <button @click="exportData" class="tool-btn">导出数据</button>
      <div class="zoom-controls">
        <button @click="zoomIn" class="tool-btn">放大</button>
        <button @click="zoomOut" class="tool-btn">缩小</button>
        <button @click="resetZoom" class="tool-btn">重置</button>
      </div>
      <div class="info">
        <span>快捷键: R - 绘制矩形, Delete - 删除选中</span>
        <span>缩放: {{ Math.round(scale * 100) }}%</span>
      </div>
    </div>
    
    <div class="canvas-container" 
         ref="canvasContainer"
         @mousedown="onMouseDown"
         @mousemove="onMouseMove"
         @mouseup="onMouseUp"
         @wheel="onWheel"
         @keydown="onKeyDown"
         tabindex="0">
      <div id="svg-container"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import SVG from 'svg.js'

// 响应式数据
const canvasContainer = ref(null)
const svgContainer = ref(null)
const draw = ref(null)
const imageElement = ref(null)
const rectangles = ref([])
const selectedRect = ref(null)
const isDrawing = ref(false)
const isDragging = ref(false)
const isResizing = ref(false)
const startPoint = ref({ x: 0, y: 0 })
const currentPoint = ref({ x: 0, y: 0 })
const scale = ref(1)
const panOffset = ref({ x: 0, y: 0 })
const isPanning = ref(false)
const lastPanPoint = ref({ x: 0, y: 0 })

// 图片信息
const imageInfo = {
  width: 800,
  height: 600,
  src: ''
}

// 初始化SVG画布
const initSVG = () => {
  const container = document.getElementById('svg-container')
  if (!container) return
  
  // 清空容器
  container.innerHTML = ''
  
  // 创建SVG画布
  draw.value = SVG(container).size('100%', '100%')
  
  // 添加背景图片
  const image = draw.value.image(imageInfo.src)
  image.size(imageInfo.width, imageInfo.height)
  image.move(0, 0)
  imageElement.value = image
  
  // 设置SVG容器样式
  container.style.width = '100%'
  container.style.height = '100%'
  container.style.position = 'relative'
  container.style.overflow = 'hidden'
}

// 键盘事件处理
const onKeyDown = (event) => {
  if (event.target !== canvasContainer.value) return
  
  switch (event.key.toLowerCase()) {
    case 'r':
      startDrawingMode()
      break
    case 'delete':
    case 'backspace':
      deleteSelectedRect()
      break
    case 'escape':
      cancelDrawing()
      break
  }
}

// 开始绘制模式
const startDrawingMode = () => {
  isDrawing.value = true
  selectedRect.value = null
  canvasContainer.value.style.cursor = 'crosshair'
}

// 取消绘制
const cancelDrawing = () => {
  isDrawing.value = false
  canvasContainer.value.style.cursor = 'default'
}

// 鼠标事件处理
const onMouseDown = (event) => {
  if (!draw.value) return
  
  const rect = canvasContainer.value.getBoundingClientRect()
  const x = (event.clientX - rect.left - panOffset.value.x) / scale.value
  const y = (event.clientY - rect.top - panOffset.value.y) / scale.value
  
  if (isDrawing.value) {
    // 绘制模式
    startPoint.value = { x, y }
    currentPoint.value = { x, y }
    isDrawing.value = true
  } else {
    // 选择模式
    const clickedRect = findRectAtPoint(x, y)
    if (clickedRect) {
      if (event.ctrlKey || event.metaKey) {
        // 多选
        if (selectedRect.value === clickedRect) {
          selectedRect.value = null
        } else {
          selectedRect.value = clickedRect
        }
      } else {
        selectedRect.value = clickedRect
      }
      
      // 检查是否点击在边缘或角落（用于缩放）
      const resizeInfo = checkResizeArea(clickedRect, x, y)
      if (resizeInfo.canResize) {
        isResizing.value = true
        startPoint.value = { x, y }
        selectedRect.value.resizeInfo = resizeInfo
      } else {
        isDragging.value = true
        startPoint.value = { x, y }
      }
    } else {
      // 点击空白区域，取消选择
      selectedRect.value = null
      isPanning.value = true
      lastPanPoint.value = { x: event.clientX, y: event.clientY }
    }
  }
}

const onMouseMove = (event) => {
  if (!draw.value) return
  
  const rect = canvasContainer.value.getBoundingClientRect()
  const x = (event.clientX - rect.left - panOffset.value.x) / scale.value
  const y = (event.clientY - rect.top - panOffset.value.y) / scale.value
  
  if (isDrawing.value && startPoint.value) {
    // 绘制矩形
    currentPoint.value = { x, y }
    updateDrawingRect()
  } else if (isDragging.value && selectedRect.value) {
    // 拖拽矩形
    const deltaX = x - startPoint.value.x
    const deltaY = y - startPoint.value.y
    moveRect(selectedRect.value, deltaX, deltaY)
    startPoint.value = { x, y }
  } else if (isResizing.value && selectedRect.value) {
    // 缩放矩形
    const deltaX = x - startPoint.value.x
    const deltaY = y - startPoint.value.y
    resizeRect(selectedRect.value, deltaX, deltaY)
    startPoint.value = { x, y }
  } else if (isPanning.value) {
    // 平移图片
    const deltaX = event.clientX - lastPanPoint.value.x
    const deltaY = event.clientY - lastPanPoint.value.y
    panImage(deltaX, deltaY)
    lastPanPoint.value = { x: event.clientX, y: event.clientY }
  } else {
    // 鼠标悬停效果
    updateHoverEffects(x, y)
  }
}

const onMouseUp = (event) => {
  if (isDrawing.value && startPoint.value && currentPoint.value) {
    // 完成绘制
    finishDrawing()
  }
  
  // 重置状态
  isDrawing.value = false
  isDragging.value = false
  isResizing.value = false
  isPanning.value = false
  canvasContainer.value.style.cursor = 'default'
  
  if (selectedRect.value && selectedRect.value.resizeInfo) {
    delete selectedRect.value.resizeInfo
  }
}

// 鼠标滚轮事件（缩放）
const onWheel = (event) => {
  event.preventDefault()
  
  const rect = canvasContainer.value.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  const zoomFactor = event.deltaY > 0 ? 0.9 : 1.1
  const newScale = Math.max(0.1, Math.min(5, scale.value * zoomFactor))
  
  // 以鼠标位置为中心进行缩放
  const scaleRatio = newScale / scale.value
  panOffset.value.x = mouseX - (mouseX - panOffset.value.x) * scaleRatio
  panOffset.value.y = mouseY - (mouseY - panOffset.value.y) * scaleRatio
  
  scale.value = newScale
  updateTransform()
}

// 更新变换
const updateTransform = () => {
  if (imageElement.value) {
    imageElement.value.transform({
      translate: [panOffset.value.x, panOffset.value.y],
      scale: scale.value
    })
  }
  
  // 更新所有矩形的变换
  rectangles.value.forEach(rect => {
    if (rect.svgElement) {
      rect.svgElement.transform({
        translate: [panOffset.value.x, panOffset.value.y],
        scale: scale.value
      })
    }
  })
}

// 绘制矩形
const updateDrawingRect = () => {
  if (!startPoint.value || !currentPoint.value) return
  
  // 清除之前的临时矩形
  if (window.tempRect) {
    window.tempRect.remove()
  }
  
  const x = Math.min(startPoint.value.x, currentPoint.value.x)
  const y = Math.min(startPoint.value.y, currentPoint.value.y)
  const width = Math.abs(currentPoint.value.x - startPoint.value.x)
  const height = Math.abs(currentPoint.value.y - startPoint.value.y)
  
  if (width > 5 && height > 5) {
    window.tempRect = draw.value.rect(width, height)
      .move(x, y)
      .fill('none')
      .stroke({ color: '#ff0000', width: 2 })
      .attr('stroke-dasharray', '5,5')
  }
}

// 完成绘制
const finishDrawing = () => {
  if (!startPoint.value || !currentPoint.value) return
  
  const x = Math.min(startPoint.value.x, currentPoint.value.x)
  const y = Math.min(startPoint.value.y, currentPoint.value.y)
  const width = Math.abs(currentPoint.value.x - startPoint.value.x)
  const height = Math.abs(currentPoint.value.y - startPoint.value.y)
  
  if (width > 5 && height > 5) {
    createRectangle(x, y, width, height)
  }
  
  // 清除临时矩形
  if (window.tempRect) {
    window.tempRect.remove()
    window.tempRect = null
  }
  
  // 重置绘制状态
  startPoint.value = null
  currentPoint.value = null
  isDrawing.value = false
  canvasContainer.value.style.cursor = 'default'
}

// 创建矩形
const createRectangle = (x, y, width, height) => {
  const rect = draw.value.rect(width, height)
    .move(x, y)
    .fill('none')
    .stroke({ color: '#007bff', width: 2 })
    .attr('data-id', Date.now())
  
  const rectData = {
    id: Date.now(),
    x,
    y,
    width,
    height,
    svgElement: rect,
    isSelected: false
  }
  
  rectangles.value.push(rectData)
  
  // 添加事件监听
  rect.on('mouseover', () => {
    if (!isDragging.value && !isResizing.value) {
      highlightRect(rectData)
    }
  })
  
  rect.on('mouseout', () => {
    if (!rectData.isSelected) {
      unhighlightRect(rectData)
    }
  })
  
  return rectData
}

// 查找点击位置的矩形
const findRectAtPoint = (x, y) => {
  // 从后往前查找（最上层的优先）
  for (let i = rectangles.value.length - 1; i >= 0; i--) {
    const rect = rectangles.value[i]
    if (x >= rect.x && x <= rect.x + rect.width &&
        y >= rect.y && y <= rect.y + rect.height) {
      return rect
    }
  }
  return null
}

// 检查是否在缩放区域
const checkResizeArea = (rect, x, y) => {
  const margin = 8
  const cornerSize = 12
  
  // 检查角落
  if (x <= rect.x + cornerSize && y <= rect.y + cornerSize) {
    return { canResize: true, type: 'nw', cursor: 'nw-resize' }
  }
  if (x >= rect.x + rect.width - cornerSize && y <= rect.y + cornerSize) {
    return { canResize: true, type: 'ne', cursor: 'ne-resize' }
  }
  if (x <= rect.x + cornerSize && y >= rect.y + rect.height - cornerSize) {
    return { canResize: true, type: 'sw', cursor: 'sw-resize' }
  }
  if (x >= rect.x + rect.width - cornerSize && y >= rect.y + rect.height - cornerSize) {
    return { canResize: true, type: 'se', cursor: 'se-resize' }
  }
  
  // 检查边缘
  if (x <= rect.x + margin && y >= rect.y && y <= rect.y + rect.height) {
    return { canResize: true, type: 'w', cursor: 'w-resize' }
  }
  if (x >= rect.x + rect.width - margin && y >= rect.y && y <= rect.y + rect.height) {
    return { canResize: true, type: 'e', cursor: 'e-resize' }
  }
  if (y <= rect.y + margin && x >= rect.x && x <= rect.x + rect.width) {
    return { canResize: true, type: 'n', cursor: 'n-resize' }
  }
  if (y >= rect.y + rect.height - margin && x >= rect.x && x <= rect.x + rect.width) {
    return { canResize: true, type: 's', cursor: 's-resize' }
  }
  
  return { canResize: false }
}

// 移动矩形
const moveRect = (rect, deltaX, deltaY) => {
  rect.x += deltaX
  rect.y += deltaY
  
  if (rect.svgElement) {
    rect.svgElement.move(rect.x, rect.y)
  }
}

// 缩放矩形
const resizeRect = (rect, deltaX, deltaY) => {
  const resizeInfo = rect.resizeInfo
  if (!resizeInfo) return
  
  switch (resizeInfo.type) {
    case 'nw':
      rect.x += deltaX
      rect.y += deltaY
      rect.width -= deltaX
      rect.height -= deltaY
      break
    case 'ne':
      rect.y += deltaY
      rect.width += deltaX
      rect.height -= deltaY
      break
    case 'sw':
      rect.x += deltaX
      rect.width -= deltaX
      rect.height += deltaY
      break
    case 'se':
      rect.width += deltaX
      rect.height += deltaY
      break
    case 'w':
      rect.x += deltaX
      rect.width -= deltaX
      break
    case 'e':
      rect.width += deltaX
      break
    case 'n':
      rect.y += deltaY
      rect.height -= deltaY
      break
    case 's':
      rect.height += deltaY
      break
  }
  
  // 确保最小尺寸
  rect.width = Math.max(10, rect.width)
  rect.height = Math.max(10, rect.height)
  
  if (rect.svgElement) {
    rect.svgElement.size(rect.width, rect.height).move(rect.x, rect.y)
  }
}

// 平移图片
const panImage = (deltaX, deltaY) => {
  panOffset.value.x += deltaX
  panOffset.value.y += deltaY
  updateTransform()
}

// 高亮矩形
const highlightRect = (rect) => {
  if (rect.svgElement) {
    rect.svgElement.stroke({ color: '#ff6b35', width: 3 })
  }
}

// 取消高亮
const unhighlightRect = (rect) => {
  if (rect.svgElement && !rect.isSelected) {
    rect.svgElement.stroke({ color: '#007bff', width: 2 })
  }
}

// 选择矩形
const selectRect = (rect) => {
  // 取消之前的选择
  if (selectedRect.value) {
    selectedRect.value.isSelected = false
    unhighlightRect(selectedRect.value)
  }
  
  selectedRect.value = rect
  rect.isSelected = true
  
  if (rect.svgElement) {
    rect.svgElement.stroke({ color: '#28a745', width: 3 })
  }
}

// 删除选中的矩形
const deleteSelectedRect = () => {
  if (selectedRect.value) {
    const index = rectangles.value.findIndex(r => r.id === selectedRect.value.id)
    if (index > -1) {
      if (selectedRect.value.svgElement) {
        selectedRect.value.svgElement.remove()
      }
      rectangles.value.splice(index, 1)
      selectedRect.value = null
    }
  }
}

// 清空所有矩形
const clearAll = () => {
  rectangles.value.forEach(rect => {
    if (rect.svgElement) {
      rect.svgElement.remove()
    }
  })
  rectangles.value = []
  selectedRect.value = null
}

// 导出数据
const exportData = () => {
  const data = {
    scale: scale.value,
    panOffset: panOffset.value,
    rectangles: rectangles.value.map(rect => ({
      id: rect.id,
      x: rect.x,
      y: rect.y,
      width: rect.width,
      height: rect.height
    }))
  }
  
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'annotation-data.json'
  a.click()
  URL.revokeObjectURL(url)
}

// 缩放控制
const zoomIn = () => {
  scale.value = Math.min(5, scale.value * 1.2)
  updateTransform()
}

const zoomOut = () => {
  scale.value = Math.max(0.1, scale.value / 1.2)
  updateTransform()
}

const resetZoom = () => {
  scale.value = 1
  panOffset.value = { x: 0, y: 0 }
  updateTransform()
}

// 更新悬停效果
const updateHoverEffects = (x, y) => {
  const hoveredRect = findRectAtPoint(x, y)
  
  // 更新鼠标样式
  if (hoveredRect) {
    const resizeInfo = checkResizeArea(hoveredRect, x, y)
    if (resizeInfo.canResize) {
      canvasContainer.value.style.cursor = resizeInfo.cursor
    } else {
      canvasContainer.value.style.cursor = 'move'
    }
  } else {
    canvasContainer.value.style.cursor = 'default'
  }
  
  // 更新高亮效果
  rectangles.value.forEach(rect => {
    if (rect !== hoveredRect && !rect.isSelected) {
      unhighlightRect(rect)
    }
  })
  
  if (hoveredRect && !hoveredRect.isSelected) {
    highlightRect(hoveredRect)
  }
}

// 生命周期
onMounted(() => {
  nextTick(() => {
    initSVG()
    // 聚焦容器以接收键盘事件
    canvasContainer.value.focus()
  })
})

onUnmounted(() => {
  // 清理资源
  if (draw.value) {
    draw.value.clear()
  }
})
</script>

<style scoped>
.annotation-page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px;
  background: white;
  border-bottom: 1px solid #e0e0e0;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.tool-btn {
  padding: 8px 16px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: white;
  cursor: pointer;
  transition: all 0.2s;
}

.tool-btn:hover {
  background: #f0f0f0;
  border-color: #999;
}

.zoom-controls {
  display: flex;
  gap: 8px;
}

.info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-left: auto;
  font-size: 12px;
  color: #666;
}

.canvas-container {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: #2c2c2c;
  cursor: default;
}

.canvas-container:focus {
  outline: none;
}

#svg-container {
  width: 100%;
  height: 100%;
  position: relative;
}

/* SVG元素样式 */
:deep(svg) {
  width: 100%;
  height: 100%;
}

:deep(rect) {
  cursor: pointer;
  transition: all 0.2s ease;
}

:deep(rect:hover) {
  filter: brightness(1.2);
}
</style>
